package ncrnadb.cli;

import java.io.File;
import java.util.Collection;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import ncrnadb.core.ORDB;
import ncrnadb.core.RID;
import ncrnadb.core.RelationFields;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;

public class Relations {

	
	public static void usage(){
		System.out.println("Usage: cmd [rid1 rid2 rid3 ... | --file ifile] ");
	}
	
	public static void main(String[] args){
		
		boolean modFile = false;
		String a_ifile = "";
		Map<Integer,  Set<String> > mRIDs = new TreeMap<Integer, Set<String>>();
		try{
			
			if(args[0].compareTo("--file") == 0){
				modFile = true;
				a_ifile = args[1];
			}
			else{
				modFile = false;
				for(int i=0; i<args.length; i++){
					Set<String> rids = new TreeSet<String>();
					rids.add(args[i]);
					mRIDs.put(i,  rids);
				}
			}
			
		}catch(Exception e){
			usage();
			System.exit(1);
		}
		
		
		try{
			if(modFile){
				Scanner scanner = new Scanner(new File(a_ifile));
				
				int n = 0;
				while(scanner.hasNextLine()){
					Set<String> rids = new TreeSet<String>();
					
					String line = scanner.nextLine();
					String[] cc = line.split("\\s+");
					
					for(int i=0; i<cc.length; i++){
						cc[i] = cc[i].trim();
						if(cc.length> 0){
							rids.add(cc[i]);
						}
					}
					
					mRIDs.put(n,  rids);
					n++;
				}
				scanner.close();
			}
			
			
			
			
			ORDB ordb = new ORDB();
			ordb.open();
			
			
			
			Map<Vertex, Set<Integer>> rvMaps = new TreeMap<Vertex, Set<Integer>>();
			
			//for each object  print:
			// - input RIDs, surrounded by [] if invalid
			// - all synonym  RIDs
			// - retrieved entities ORIDs
			for(Map.Entry<Integer, Set<String>> aList : mRIDs.entrySet()){
				Integer aID = aList.getKey();
				
				Set<String> sMap = new TreeSet<String>();
				Set<String> rMap = new TreeSet<String>();
				Set<String> vMap = new TreeSet<String>();
				
				
				for(String s : aList.getValue()){
					RID rid = RID.get(s);
					if(rid == null){
						sMap.add("["+rid+"]");
					}
					else{
						sMap.add(rid.toString());
						
						Collection<Vertex> entities = ordb.getEntities(rid);
						
						for(Vertex v : entities){
							vMap.add(v.getId().toString());
							
							Set<Integer> rvMap = rvMaps.get(v);
							if(rvMap == null){
								rvMap = new TreeSet<Integer>();
								rvMaps.put(v, rvMap);
							}
							rvMap.add(aID);
							
						}
						Collection<RID> rids = ordb.getRIDs(entities);
						for(RID r : rids){
							rMap.add(r.toString());
						}
					}
		
				}
				
				System.out.println("@V\t"+aID);
				System.out.print("#input "); for(String s : sMap) System.out.print(s+"\t"); System.out.println();
				System.out.print("#synonims "); for(String s : rMap) System.out.print(s+"\t"); System.out.println();
				System.out.print("#EIDs "); for(String s : vMap) System.out.print(s+"\t"); System.out.println();
			}
			
			
			
			Set<Edge> edges = new TreeSet<Edge>();
			Map<Edge, Integer> eMap = new TreeMap<Edge, Integer>();
	
			int eID = 0;
			for(Edge ed : ordb.getRelationsAmong(rvMaps.keySet())){
				edges.add(ed);
				eMap.put(ed, eID);
				
				RelationFields rfs = ordb.getFields(ed); 
				System.out.print("@E\t"+eID+"\t"+ed.getId().toString()+"\t");
				System.out.println(rfs.source.compact()+"\t"+rfs.level+"\t"+rfs.pubmedID+"\t"+rfs.supportSentence);
				
				eID++;
			}
			
			for(Map.Entry<Edge, Integer> ee : eMap.entrySet()){
				Edge ed = ee.getKey();
				eID = ee.getValue();
				
				Set<Integer> vs1 = rvMaps.get(ed.getVertex(Direction.OUT));
				Set<Integer> vs2 = rvMaps.get(ed.getVertex(Direction.IN));
				
				for(Integer v1 : vs1){
					for(Integer v2 : vs2){
						System.out.println("@R\t"+v1+"\t"+v2+"\t"+eID);
					}
				}
			}
			
			
			ordb.close();
			
		}catch(Exception e){
			e.printStackTrace();
			System.out.println(e);
			System.exit(1);
		}
	}
}
